const fs = require("fs");
const { spawnSync } = require("child_process");
let all = [];
function genProvinces ()
{
    let files = fs.readdirSync("./data/geo/province");
    files.map((file,index) => {
        let province = JSON.parse(fs.readFileSync(`./data/geo/province/${file}`, { encoding: "utf-8" }));
        parse(province);
    });
    function parse (province)
    {
        let coordinates = (province.features[0].geometry.coordinates[0][0]);
        let lat_min = 90;
        let lat_max = -90;
        let lng_min = 180;
        let lng_max = -180;
        coordinates.map((coordinate) =>
        {
            lat_min = Math.min(lat_min, coordinate[1]);
            lat_max = Math.max(lat_max, coordinate[1]);
            lng_min = Math.min(lng_min, coordinate[0]);
            lng_max = Math.max(lng_max, coordinate[0]);
        });
        let p = { c: province.features[0].properties.adcode,n: province.features[0].properties.name,r:[lat_min,lat_max,lng_min,lng_max] };
        all.push(p);
    }
}
function genDistricts ()
{
    let files = fs.readdirSync("./data/geo/district");
    files.map((file,index) => {
        let district = JSON.parse(fs.readFileSync(`./data/geo/district/${file}`, { encoding: "utf-8" }));
        parse(district);
    });
    function parse (district)
    {
        let coordinates = (district.features[0].geometry.coordinates[0][0]);
        let lat_min = 90;
        let lat_max = -90;
        let lng_min = 180;
        let lng_max = -180;
        coordinates.map((coordinate) =>
        {
            lat_min = Math.min(lat_min, coordinate[1]);
            lat_max = Math.max(lat_max, coordinate[1]);
            lng_min = Math.min(lng_min, coordinate[0]);
            lng_max = Math.max(lng_max, coordinate[0]);
        });
        let p = { c: district.features[0].properties.adcode, n: district.features[0].properties.name, r:[lat_min, lat_max, lng_min, lng_max] };
        let parent = all.filter((item) => { return item.c == district.features[0].properties.parent.adcode });
        if (parent.length == 1)
        {
            parent[0].s = parent[0].s || [];
            parent[0].s.push(p);
        }
        else
        {
            let provice = all.filter((item) => { return item.c == Math.floor(district.features[0].properties.parent.adcode / 10000) * 10000; })[0];
            let city = provice.s.filter((item) => { return item.c == district.features[0].properties.parent.adcode });
            if (city.length == 1)
            {
                city[0].s = city[0].s || [];
                city[0].s.push(p);
            }
        }
    }
}

function genCities ()
{
    let files = fs.readdirSync("./data/geo/city");
    files.map((file,index) => {
        let city = JSON.parse(fs.readFileSync(`./data/geo/city/${file}`, { encoding: "utf-8" }));
        parse(city);
    });
    function parse (city)
    {
        let coordinates = (city.features[0].geometry.coordinates[0][0]);
        let lat_min = 90;
        let lat_max = -90;
        let lng_min = 180;
        let lng_max = -180;
        coordinates.map((coordinate) =>
        {
            lat_min = Math.min(lat_min, coordinate[1]);
            lat_max = Math.max(lat_max, coordinate[1]);
            lng_min = Math.min(lng_min, coordinate[0]);
            lng_max = Math.max(lng_max, coordinate[0]);
        });
        let p = { c: city.features[0].properties.adcode, n: city.features[0].properties.name, r:[lat_min, lat_max, lng_min, lng_max] };
        let parent = all.filter((item) => { return item.c == city.features[0].properties.parent.adcode });
        if (parent.length == 1)
        {
            parent[0].s = parent[0].s || [];
            parent[0].s.push(p);
        }
    }
}
// genProvinces();
// genCities();
// genDistricts();
// fs.writeFileSync("./data/geo/geo.json", JSON.stringify(all));
// spawnSync(`mini-program-pack${process.platform === 'win32' ? '.cmd' : ''}`, ["-t", "geo.json", "-p", "./data/geo", "-o", "./data/geo/geo.wasm.br"]);

function geo2address (lng, lat)
{
    let geo = JSON.parse(fs.readFileSync("./data/geo/geo.json", { encoding: "utf-8" }));
    let address = [];
    let dist = [];
    geo.map(province =>
    {
        if (lng >= province.r[2] && lng <= province.r[3] && lat >= province.r[0] && lat <= province.r[1])
        {
            address.push([province.n]);
            if (province.s)
            {
                let inRegion = false;
                province.s.map(city =>
                {
                    if (lng >= city.r[2] && lng <= city.r[3] && lat >= city.r[0] && lat <= city.r[1])
                    {
                        inRegion = true;
                        if (address[address.length - 1].length < 2)
                        {
                            address[address.length - 1].push(city.n);
                        }
                        else
                        {
                            address.push([address[address.length - 1][0],city.n]);
                        }
                        if (city.s)
                        {
                            let inRegion = false;
                            city.s.map(district =>
                            {
                                if (lng >= district.r[2] && lng <= district.r[3] && lat >= district.r[0] && lat <= district.r[1])
                                {
                                    if (address[address.length - 1].length < 3)
                                    {
                                        address[address.length - 1].push(district.n);
                                    }
                                    else
                                    {
                                        address.push([address[address.length - 1][0], address[address.length - 1][1], district.n]);
                                    }
                                    dist.push(Math.sqrt(Math.pow(lng - (district.r[2]+district.r[3])/2, 2) + Math.pow(lat - (district.r[0]+district.r[1])/2, 2)));
                                    inRegion = true;
                                }
                            });
                            if (!inRegion)
                            {
                                address[address.length - 1].pop();
                            }
                        }
                        else
                        {
                            dist.push(Math.sqrt(Math.pow(lng - (city.r[2]+city.r[3])/2, 2) + Math.pow(lat - (city.r[0]+city.r[1])/2, 2)));
                        }
                    }
                });
                if (!inRegion)
                {
                    address.pop();
                }
            }
        }
    });
    let raw = dist.map(item=>item);
    dist.sort((a, b) => { return a - b });
    let index = raw.indexOf(dist[0]);
    if (index > -1)
    {
        return address[index];
    }
    return [];
}
// console.log(geo2address(114.1, 22.7));
// console.log(geo2address(116.48548, 39.9484));
// console.log(geo2address(119.95, 27.78));
// console.log(geo2address(121.6739, 24.91571));
// console.log(geo2address(0, 0));
// console.log(fs.readdirSync("./data/geo/district").map(item => { return "./data/geo/district/" + item }).join(" "))
// spawnSync(`mini-program-pack${process.platform === 'win32' ? '.cmd' : ''}`, ["-t","*.json","-p", "./data/geo/district", "-o", "./data/geo/district.wasm.br"]);
//mini-program-pack.cmd -p ./data/geo/district -o ./data/geo/district.wasm.br
let fd = fs.openSync("./data/geo/geo.json", "r");
let buf = new Array(1024);
let buffer = Buffer.from([]);
let len = fs.readSync(fd, buffer, 0, 1024);
console.log(buffer.toString(), len);